#! C:\Python26x86\python.exe
import sys
from AssemblerUtils import int2bin
from AssemblerUtils import decodeNum

'''
Created on Mar 30, 2010

The easiest way to use this assembler is to drag and drop an assembly file
on its icon in windows explorer. Alternatively you could pass the path of an
assembly file to this script via command line.

Check out the README Python Assembler Script.docx file for instructions
on writing your own assembly file.

@author: Jeff
'''

def ParseAssemblyFile(filename):
	global ptrmap
	global mem
	ptrmap = {}
	mem = []
	
	try:
		infile = open(filename, 'r')
	except:
		print "Could not open assemble file: %s" % filename
		return
	
	#initialize memory array
	for i in range(0, 512-len(mem)):
		mem.append("")
	
	varNum = FindVariables(infile)
	remainingInstructions = 512 - varNum
	
	if remainingInstructions == -1:
		print "ERROR!!! too many variables"
		return -1
	
	remainingInstructions = FindInstructions(infile, remainingInstructions)
	infile.close()
	
	if remainingInstructions == -1:
		print "ERROR!!! too many instructions"
		return -1
	
	FindPointers()
	
	#outputfile
	#j = filename.rfind(".")
	#outname = filename[:j]
	outname = None
	j = filename.rfind("\\")
	if mode == "coe":
		outname = "".join([filename[:j+1], "AssemblyCode"])
	elif mode == "sim":
		outname = "".join([filename[:j+1], "microram_sim"])
	if mode == "coe":
		outname = "".join([outname, ".coe"])
	elif mode == "sim":
		outname = "".join([outname, ".vhd"])
	try:
		outfile = open(outname, 'w')
	except:
		print "Could not open output file: %s" % outname
		

	if mode == "coe":
		#start .coe file
		outfile.write("; Coefficient file for initializing a 512x8 RAM\n")
		outfile.write("; to demonstrate CPU functionality.\n")
		outfile.write(";\n")
		outfile.write("memory_initialization_radix = 2;\n")
		outfile.write("memory_initialization_vector =\n")
		
	elif mode == "sim":
		outfile.write("--\n")
		outfile.write("-- This file simulates a 512x8 synchronous RAM component.\n")
		outfile.write("--\n")
		outfile.write("-- The program to be executed is encoded by initializing\n")
		outfile.write("-- the \"mem_data\" signal (see below).\n")
		outfile.write("--\n")
		outfile.write("--\n")
		outfile.write("\n")
		outfile.write("LIBRARY IEEE;\n")
		outfile.write("USE IEEE.std_logic_1164.all;\n")
		outfile.write("USE IEEE.std_logic_arith.all;\n")
		outfile.write("USE IEEE.std_logic_unsigned.all;\n")
		outfile.write("\n")
		outfile.write("ENTITY microram IS\n")
		outfile.write("	PORT (  CLOCK   : IN STD_LOGIC ;\n")
		outfile.write("			ADDRESS : IN STD_LOGIC_VECTOR (8 DOWNTO 0);\n")
		outfile.write("			DATAOUT : OUT STD_LOGIC_VECTOR (15 DOWNTO 0);\n")
		outfile.write("			DATAIN  : IN STD_LOGIC_VECTOR (15 DOWNTO 0);\n")
		outfile.write("			WE      : IN STD_LOGIC \n")
		outfile.write("	);\n")
		outfile.write("END ENTITY microram;\n")
		outfile.write("\n")
		outfile.write("ARCHITECTURE a OF microram IS\n")
		outfile.write("   TYPE t_mem_data IS ARRAY(0 to 511) of std_logic_vector(15 downto 0);\n")
		outfile.write("\n")
		outfile.write("   -- Your program is entered here, as initialization values for\n")
		outfile.write("   -- the \"mem_data\" signal.\n")
		outfile.write("   SIGNAL mem_data: t_mem_data :=\n")
		outfile.write("	   ( \n")

	#write memory
	for i in range(0, len(mem)):
		str = mem[i]
		if len(str) == 0:	#filler code
			if mode == "coe":
				outfile.write("0000000000000000\n")
			#elif mode == "sim":
			#	str = "%u => \"0000000000000000\",\t-- filler\n" % i
		else:
			if mode == "sim":
				outfile.write("		 ")	
			outfile.write(str)
	
	if mode == "coe":
		#add .coe end file code
		outfile.write(";\n")
	elif mode == "sim":
		outfile.write("\n")
		outfile.write("		 others => \"0000000000000000\"  -- all other memory locations set to 0\n")
		outfile.write("			);\n")
		outfile.write("BEGIN\n")
		outfile.write("   RAM_Process: process(CLOCK)\n")
		outfile.write("		VARIABLE memaddr : INTEGER RANGE 0 TO 511;\n")
		outfile.write("   BEGIN\n")
		outfile.write("\n")
		outfile.write("		IF rising_edge(CLOCK) THEN\n")
		outfile.write("		  memaddr := CONV_INTEGER(ADDRESS);\n")
		outfile.write("		  IF we='1' THEN\n")
		outfile.write("			 mem_data(memaddr) <= DATAIN;\n")
		outfile.write("			 DATAOUT <= DATAIN;\n")
		outfile.write("		  ELSE\n")
		outfile.write("			 DATAOUT <= mem_data(memaddr);\n")
		outfile.write("		  END IF;\n")
		outfile.write("		END IF;\n")
		outfile.write("	END PROCESS;\n")
		outfile.write("\n")
		outfile.write("END ARCHITECTURE a;	\n")	
		outfile.close()

	if remainingInstructions == 0:
		print "ERROR! There are too many lines in your assemble code"
	else:
		print "There are %u lines in your assemble code" % (512 - remainingInstructions)

def FindInstructions(file, instructionsLeft):
	file.seek(0)
	instructionNum = 0
	for line in file:
		str = line.strip()
		if len(str) < 1:
			continue
		temp = str[0:4]
		if temp.upper() == "VAR_":
			continue	#skip variable lines
		elif str[0:2] == "--":
			#memline = "".join([memline, str, "\n"])	#store comments for next line comments
			continue
		else:
			instructionNum = InstructionLine(str, instructionNum)
#		print instructionsLeft,instructionNum
				
	return instructionsLeft-instructionNum

def InstructionLine(str, instructionNum):
	#TODO
	line = str.strip().upper()
	#print instructionNum
	
	###########################################################
	cmd = "SINLUT"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001000111"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
		
		r = args[1].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "LOAD"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "00000000000000"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		r = args[1].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, p, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, p, "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "STOR"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "00000000000001"
		
		temp = args[1].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, p, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, p, "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "JMP"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000000001110"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		instruction = "".join([instruction, p])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "CHKTMR"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001001001"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		instruction = "".join([instruction, p])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "BNZ"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000000001001"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		instruction = "".join([instruction, p])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "BZ"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000000001010"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		instruction = "".join([instruction, p])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "BN"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001001010"
		
		temp = args[0].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		instruction = "".join([instruction, p])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "BRSET"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "00000000011"
		
		temp = args[2].strip()
		if temp[0] != '&':
			m = decodeNum(temp)
			if m < 256:
				p = '0'
			else:
				p = '1'
				m -= 256
			m = int2bin(m,16)
		else:
			temp2 = temp[1:]
			i = temp2.find('&')
			m = temp[:i+2]
			p = ''
		
		r = args[0].strip().upper()
		bits = decodeNum(args[1].strip())
		if r[0] == 'A':
			instruction = "".join([instruction, "0", int2bin(bits, 3), p])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1", int2bin(bits, 3), p])
		
		if len(args) > 3:
			temp = args[3]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[3]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		instruction = m
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- memory pointer %s" % m])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "ADD"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001000000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "SUB"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001001000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "LSL"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001010000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "LSR"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001011000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "XOR"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001100000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "COM"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001101000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "NEG"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001110000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "MULT"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000000001111"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "OUT"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		
		r = args[0].strip().upper()
		p = decodeNum(args[1].strip().upper())
		if p < 2:
			instruction = "00000000000010"
		elif p < 4:
			instruction = "00000000100111"
			p -= 2
		if r[0] == 'A':
			instruction = "".join([instruction, ("%1u" % p), "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, ("%1u" % p), "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "IN"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "00000000000011"
		
		r = args[1].strip().upper()
		p = decodeNum(args[0].strip().upper())
		if r[0] == 'A':
			instruction = "".join([instruction, ("%1u" % p), "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, ("%1u" % p), "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "CPSE"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "0000000000010110"
		
		if len(args) > 0:
			temp = args[0]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[0]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "CLRWDT"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "0000000000010111"
		
		if len(args) > 0:
			temp = args[0]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[0]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "CLR"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000001111000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "BCDO"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "000000000001000"
		
		r = args[0].strip().upper()
		if r[0] == 'A':
			instruction = "".join([instruction, "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, "1"])
		
		if len(args) > 1:
			temp = args[1]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[1]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	###########################################################
	cmd = "DEB"
	temp = line.strip()
	temp = temp[:len(cmd)]
	i = temp.find(cmd)
	if i >= 0:
		args = line[i+len(cmd):].strip().split(',')
		instruction = "00000000000110"
		
		r = args[1].strip().upper()
		n = decodeNum(args[0].strip().upper())
		if r[0] == 'A':
			instruction = "".join([instruction, ("%1u" % n), "0"])
		elif r[0] == 'B':
			instruction = "".join([instruction, ("%1u" % n), "1"])
		
		if len(args) > 2:
			temp = args[2]
			s = temp.find('*')
			temp = temp[s+1:]
			e = temp.find('*')
			e += s
			temp = args[2]
			if e >= 0 and s >= 0:
				key = temp[s+1:e+1]
				ptrmap[key] = instructionNum
			
		if mode == "sim":
			instruction = "".join([("%u => \"") % instructionNum, instruction, "\",\t-- ", line])
		instruction = "".join([instruction, "\n"])
		mem[instructionNum] = instruction
		instructionNum += 1
		
		return instructionNum
	
	
################################################################################################
def FindPointers():
	for i in range(0, len(mem)):
		line = mem[i]
		c = line.find('--')
		k = line.find('&')
		if k == -1 or (c < k and c != -1):
			continue
		temp = line[k+1:]
		j = temp.find('&')
		j += k
		if k != -1 and j != -1 and k != j:
			key = line[k+1:j+1]
			num = ptrmap[key]
			if num > 255:
				num -= 256
				p = '1'
			else:
				p = '0'
			str = int2bin(num,16)
			line = "".join([line[:k], str, line[j+2:]])
			mem[i] = line
			
			#add page number to previous instruction
			line = mem[i-1]
			if mode == "coe":
				k = line.find('0')
				j = line.find('1')
	
				if k == -1 and j == -1:
					print "PROBLEMS can't find instruction to edit"
				elif k == -1:
					k = j
				
				if j != -1 and k != -1 and j < k:
					k = j
			elif mode == "sim":
				k = line.find("\"")
				k += 1
			
			if line[k:k+6+8] == "00000000000000" or line[k:k+6+8] == "00000000000001":
				line = "".join([line[:k+6+8], p, line[k+6+8:]])
			elif line[k:k+6+9] == "000000001000111":
				pass
			else:
				line = "".join([line[:k+7+8], p, line[k+7+8:]])
			mem[i-1] = line

def FindVariables(file):
	varnum = 0;
	lines = list()
	for line in file:
		lines.append(line)
	lines.reverse()
	
	for line in lines:
		if varnum == 512:
			break
		str = line.strip().split('=')
		temp = str[0].strip()
		temp2 = temp[0:4]
		if temp2.upper() == "VAR_":
			ptrmap[temp] = 511-varnum
			mem[511-varnum] = int2bin(decodeNum(str[1].strip()),16)
			if mode == "sim":
				mem[511-varnum] = "".join([("%u => \"") % (511-varnum), mem[511-varnum], "\",\t-- ", line.strip()])
			mem[511-varnum] = "".join([mem[511-varnum], "\n"])
			varnum = varnum+1		
	return varnum

if __name__ == '__main__':
	files = []
	global mode
	mode = "both"
	
	#test code
	#files.append("C:\\EGR426Projects\\microcontroller\\AssemblyBouncingBall.asm")
	#files.append("C:\\EGR426Projects\\microcontroller\\AssemblySINLUTtest.asm")
	#files.append("C:\\EGR426Projects\\microcontroller\\AssemblyMULTtest.asm")
	#files.append("C:\\EGR426Projects\\microcontroller\\AssemblyCHKTMRtest.asm")
	#files.append("C:\\EGR426Projects\\microcontroller\\AssemblyBNtest.asm")
	
	for arg in sys.argv:
		if arg.endswith(".asm"):
			files.append(arg)

		#find -mode=????? arguments
		i = arg.lower().find("mode")
		if  i != -1:
			str = arg[i:]
			if str.find("coe") != -1:
				mode = "coe"
			elif str.find("sim") != -1:
				mode = "sim"			
	
	if mode == "both":
		both = True	
	else:
		both = False
		
	for file in files:
		if both:
			mode = "coe"
			ParseAssemblyFile(file)
			mode = "sim"
			ParseAssemblyFile(file)
		else:
			ParseAssemblyFile(file)
